Skip to content

Fail cleanly on non-Object input instead of throwing NullPointerException - #91

Merged
cowtowncoder merged 7 commits into
FasterXML:3.xfrom
pjfanning:fix-javax-money-non-object-input
Sep 15, 2026
Merged

cowtowncoder merged 7 commits into
FasterXML:3.xfrom
pjfanning:fix-javax-money-non-object-input

Conversation

@pjfanning

Copy link
Copy Markdown
Member

Problem

MonetaryAmountDeserializer.deserialize() assumes it is positioned on a START_OBJECT:

while (parser.nextToken() != JsonToken.END_OBJECT) {
    final String field = parser.currentName();

    parser.nextToken();

    if (field.equals(names.getAmount())) {

For any non-Object input, currentName() returns null and the very next line dereferences it. A bare NPE escapes to the caller instead of a JacksonException:

input read as MonetaryAmount before
12 NullPointerException: Cannot invoke "String.equals(Object)" because "field" is null
"abc" same
[1,2] same

moneta's FastMoney / Money / RoundedMoney deserializers share this class, so they are affected too.

Fix

Check the token up front — the same thing joda-money's MoneyDeserializer already does — and only loop while actually positioned on a PROPERTY_NAME, so malformed content cannot fall into the same trap:

Cannot deserialize value of type `javax.money.MonetaryAmount` from Integer value ...

Also removes a duplicated import javax.money.CurrencyUnit; import javax.money.MonetaryAmount; pair at the top of the file.

Tests

New FailOnNonObjectTest (7 cases): number/string/array/empty-array input, a bad element inside a List<MonetaryAmount>, plus checks that valid Objects and explicit null still deserialize.

javax-money 142 tests and moneta 137 tests all green.

pjfanning and others added 2 commits September 9, 2026 10:12
`MonetaryAmountDeserializer.deserialize()` assumes it is positioned on a
START_OBJECT and loops with:

    while (parser.nextToken() != JsonToken.END_OBJECT) {
        final String field = parser.currentName();
        ...
        if (field.equals(names.getAmount())) {

For any non-Object input `currentName()` returns `null`, so a bare
`NullPointerException: Cannot invoke "String.equals(Object)" because "field"
is null` escapes to the caller rather than a `JacksonException`. Inputs `12`,
`"abc"` and `[1,2]` all reproduce it, and `moneta`'s `FastMoney`/`Money`/
`RoundedMoney` deserializers share this class.

Verify the token up front (as joda-money's `MoneyDeserializer` already does),
and only loop while positioned on a PROPERTY_NAME so malformed content cannot
fall into the same trap. Also drop a duplicated import pair.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@cowtowncoder cowtowncoder changed the title (javax-money) Fail cleanly on non-Object input instead of throwing NullPointerException Fail cleanly on non-Object input instead of throwing NullPointerException Sep 15, 2026
@cowtowncoder cowtowncoder added the javax-money Issue related javax-money datatype module label Sep 15, 2026
@cowtowncoder
cowtowncoder merged commit bfe0605 into FasterXML:3.x Sep 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javax-money Issue related javax-money datatype module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants